<?php
/**
 * Created by PhpStorm.
 * User: ari
 * Date: 9/17/14
 * Time: 8:14 AM
 */
namespace BC\User;

use BC\PGP\Commands\PGPSearchCommand;
use BC\PGP\PGPConfig;
use BC\SiteIndex;
use CPath\Build\IBuildable;
use CPath\Build\IBuildRequest;
use CPath\Render\HTML\Attribute\IAttributes;
use CPath\Render\HTML\Element\Form\HTMLForm;
use CPath\Render\HTML\Element\Form\HTMLInputField;
use CPath\Render\HTML\Element\Form\HTMLSubmit;
use CPath\Render\HTML\Element\HTMLElement;
use CPath\Render\HTML\Header\HTMLMetaTag;
use CPath\Render\HTML\IRenderHTML;
use CPath\Render\Map\MapRenderer;
use CPath\Request\Executable\IExecutable;
use CPath\Request\IRequest;
use CPath\Response\IResponse;
use CPath\Route\IRoutable;
use CPath\Route\RouteBuilder;

class Search implements IRoutable, IExecutable, IBuildable, IRenderHTML // , ITestable
{
	const PATH_FORMAT = '/users/%s';

	const PARAM_SEARCH = 'search';
	const PARAM_SEARCH_MODE = 'search_mode';

    const SES_CHALLENGE = 'challenge';

	private $mForm;

	private $pSearch;
	private $pSearchMode;
	private $pSubmit;

	public function __construct() {
		$this->mForm = new HTMLForm('GET', null, 'form-search',
			new HTMLMetaTag(HTMLMetaTag::META_TITLE, 'User Search'),

			new HTMLElement('h2', 'content-title', 'User Search'),

			'Enter user search',
			$this->pSearch =      new HTMLInputField(self::PARAM_SEARCH),
			$this->pSearchMode =  new HTMLInputField(self::PARAM_SEARCH_MODE),
			$this->pSubmit =      new HTMLSubmit('Search')

		);
	}

	/**
	 * Execute a command and return a response. Does not render
	 * @param \CPath\Request\Form\IFormRequest|\CPath\Request\IRequest $Request
	 * @throws \CPath\Request\Exceptions\RequestException
	 * @return IResponse the execution response
	 */
	function execute(IRequest $Request) {
		$Form = $this->mForm;
//		if(!$Request instanceof IFormRequest)
//			return $Form; // ->getResponse("Registration Form");

		$search = $Form->validateField($Request, self::PARAM_SEARCH);
		$searchMode = $Form->validateField($Request, self::PARAM_SEARCH_MODE);

		if(!$search)
			return $Form;

		$Search = new PGPSearchCommand($search, $searchMode);
		$Search->addKeyRing(PGPConfig::$KEYRING_USER);
		$Search->execute($Request);
		return $Search;
//		$UserSearch->execute($Request);
//
//		return new RenderableResponse(
//			$UserSearch->getMessage(),
//			$UserSearch->getCode(),
//			$Form,
//			$UserSearch
//		);
    }

	/**
	 * Render request as html
	 * @param IRequest $Request the IRequest inst for this render which contains the request and remaining args
	 * @param IAttributes $Attr
	 * @param IRenderHTML $Parent
	 * @return String|void always returns void
	 */
	function renderHTML(IRequest $Request, IAttributes $Attr = null, IRenderHTML $Parent = null) {
		$Form = $this->mForm;
		$Form->renderHTML($Request, $Attr, $Parent);
		$search = $Form->validateField($Request, self::PARAM_SEARCH);
		$searchMode = $Form->validateField($Request, self::PARAM_SEARCH_MODE);
		if($search) {
			$UserSearch = new PGPSearchCommand($search, $searchMode);
			$UserSearch->addKeyRing(PGPConfig::$KEYRING_USER);
			$UserSearch->execute($Request);

			$Mapper = new MapRenderer($UserSearch);
			$Renderer = $Mapper->getRenderer($Request);
			$Renderer->renderHTML($Request, null, $Parent);
		}
	}

    // Static

	/**
	 * Route the request to this class object and return the object
	 * @param IRequest $Request the IRequest inst for this render
	 * @param Object[]|null $Previous all previous response object that were passed from a handler, if any
	 * @param null|mixed $_arg [varargs] passed by route map
	 * @return void|bool|Object returns a response object
	 * If nothing is returned (or bool[true]), it is assumed that rendering has occurred and the request ends
	 * If false is returned, this static handler will be called again if another handler returns an object
	 * If an object is returned, it is passed along to the next handler
	 */
	static function routeRequestStatic(IRequest $Request, Array &$Previous=array(), $_arg=null) {
		$UserSearch = new Search();
		return $UserSearch;
	}

    /**
     * Handle this request and render any content
     * @param IBuildRequest $Request the build request inst for this build session
     * @return void
     * @build --disable 0
     * Note: Use doctag 'build' with '--disable 1' to have this IBuildable class skipped during a build
     */
    static function handleBuildStatic(IBuildRequest $Request) {
	    $RouteBuilder = new RouteBuilder($Request, new SiteIndex());
	    $RouteBuilder->writeRoute('ANY ' . sprintf(self::PATH_FORMAT, ':' . self::PARAM_SEARCH . '/'), __CLASS__);
	    $RouteBuilder->writeRoute('ANY ' . sprintf(self::PATH_FORMAT, ''), __CLASS__);
    }
}

